// CommandParser.h
#pragma once

#include <Arduino.h>
#include <functional>
#include <vector>

#define MAX_CMD_LENGTH 512
#define MAX_ARGS 20
#define PROMPT "esp32> "

// 流程控制字符
#define CTRL_S 0x13 // DC3 - 暂停输出/禁止输入
#define CTRL_Q 0x11 // DC1 - 恢复输出/允许输入
#define CTRL_R 0x12 // DC2 - 等待输入状态

enum ParseState
{
    STATE_NORMAL,
    STATE_IN_QUOTE,
    STATE_IN_ESCAPE,
    STATE_CONTINUATION
};

struct Command
{
    String mainCmd;
    String subCmd;
    std::vector<String> args;
    std::vector<String> namedArgs;
    std::vector<String> namedValues;
};

typedef std::function<void(const Command &cmd)> CommandHandler;

class CommandParser
{
private:
    char buffer[MAX_CMD_LENGTH];
    uint16_t bufferIndex;
    ParseState state;
    bool inContinuation;

    CommandHandler *handlers;
    char **handlerNames;
    uint8_t handlerCount;
    uint8_t maxHandlers;

    String currentToken;
    bool isNamedArg;
    bool waitingForInput;
    String expectedParam;
    Command partialCommand;

    void resetParser();
    void parseLine(const String &line);
    void executeCommand(const Command &cmd);
    void sendFlowControl(char ctrlChar);
    void promptForInput(const String &paramName);

public:
    CommandParser(uint8_t maxHandlers = 30);
    ~CommandParser();

    void update();
    void processChar(char c);
    void registerCommand(const String &cmdName, CommandHandler handler);
    void sendResponse(const String &category, const String &message);
    void sendRaw(const String &data);

    // 流程控制
    void beginOutput();
    void endOutput();
    void waitForInput(const String &prompt = "");

    // 工具方法
    static String getNamedArg(const Command &cmd, const String &name, const String &defaultValue = "");
    static int getNamedArgInt(const Command &cmd, const String &name, int defaultValue = 0);
    static bool getNamedArgBool(const Command &cmd, const String &name, bool defaultValue = false);
    static String getPositionalArg(const Command &cmd, int index, const String &defaultValue = "");
};